package com.itheima.web.service.impl.ums;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.service.ums.*;
import com.itheima.vo.ums.*;
import com.itheima.web.mapper.ums.RoleMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@DubboService
public class RoleServiceImpl extends ServiceImpl<RoleMapper, UmsRole> implements RoleService {
    @Autowired
    private MenuService menuService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private RoleResourceService roleResourceService;

    @Override
    public Page<UmsRole> getPage(Integer pageNum, Integer pageSize, String keyword) {
        Page<UmsRole> rolePage = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<UmsRole> lqw = new LambdaQueryWrapper<>();
        if(keyword != null) {
            try {
                String decode = URLDecoder.decode(keyword, "utf-8");

                lqw.like(UmsRole::getName, decode);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        this.page(rolePage,lqw);

        return rolePage;
    }

    @Override
    public Integer deleteById(Integer[] ids) {
        List<Integer> list = Arrays.asList(ids);
        List<UmsRole> umsRoles = this.listByIds(list);
        if(umsRoles == null){
            return 0;
        }
        //无绑定用户，删除角色
        this.removeBatchByIds(list);
        return 1;
    }

    @Override
    public void updateStatus(Integer id, Integer status) {
        UmsRole role = this.getById(id);
        role.setStatus(status);

        this.updateById(role);
    }

    @Override
    public List<UmsMenu> listMenu(Integer roleId) {
        LambdaQueryWrapper<RoleMenu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RoleMenu::getRoleId,roleId);
        List<RoleMenu> list = roleMenuService.list(lqw);

        List<Integer> menuIds = new ArrayList<>();
        for (RoleMenu roleMenu : list) {
            menuIds.add(roleMenu.getMenuId());
        }

        return menuService.listByIds(menuIds);
    }

    @Override
    public List<UmsResource> listResource(Integer roleId) {
        LambdaQueryWrapper<RoleResource> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RoleResource::getRoleId,roleId);
        List<RoleResource> list = roleResourceService.list(lqw);

        List<Integer> resourceIds = new ArrayList<>();
        for (RoleResource roleResource : list) {
            resourceIds.add(roleResource.getResourceId());
        }

        return resourceService.listByIds(resourceIds);
    }

    @Override
    @Transactional
    public void allocMenu(Integer roleId, Integer[] menuIds) {
        LambdaQueryWrapper<RoleMenu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RoleMenu::getRoleId,roleId);
        roleMenuService.remove(lqw);

        List<RoleMenu> roleMenus = new ArrayList<>();
        for (Integer menuId : menuIds) {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenus.add(roleMenu);
        }

        roleMenuService.saveBatch(roleMenus);
    }

    @Override
    @Transactional
    public void allocRescource(Integer roleId, Integer[] resourceIds) {
        LambdaQueryWrapper<RoleResource> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RoleResource::getRoleId,roleId);
        roleResourceService.remove(lqw);

        List<RoleResource> roleResources = new ArrayList<>();
        for (Integer resourceId : resourceIds) {
            RoleResource roleResource = new RoleResource();
            roleResource.setRoleId(roleId);
            roleResource.setResourceId(resourceId);
            roleResources.add(roleResource);
        }

        roleResourceService.saveBatch(roleResources);
    }
}
